import $ from 'jquery';

let util = {
    supportsNativeHls: function(){//移动设备对m3u8原生解析是否支持
        var a = document.createElement("video");
        var b = ["application/vnd.apple.mpegurl", "audio/mpegurl", "audio/x-mpegurl", "application/x-mpegurl", "video/x-mpegurl", "video/mpegurl", "application/mpegurl"];
        return b.some(function(b) {
            return /maybe|probably/i.test(a.canPlayType(b))
        });
    },
    supportsMSE: function(){
        var mediaSource = window.MediaSource || window.WebKitMediaSource;
        var sourceBuffer = window.SourceBuffer || window.WebKitSourceBuffer;
        var isTypeSupported = mediaSource && typeof mediaSource.isTypeSupported === 'function' && mediaSource.isTypeSupported('video/mp4; codecs="avc1.42E01E,mp4a.40.2"');

        // if SourceBuffer is exposed ensure its API is valid
        // safari and old version of Chrome doe not expose SourceBuffer globally so checking SourceBuffer.prototype is impossible
        var sourceBufferValidAPI = !sourceBuffer || (sourceBuffer.prototype && typeof sourceBuffer.prototype.appendBuffer === 'function' && typeof sourceBuffer.prototype.remove === 'function');
        return !!isTypeSupported && !!sourceBufferValidAPI;
    },
    // touch事件封装：单击、双击、n次联击、左屏拖拽、右屏拖拽、横屏拖拽、瞬时速度，瞬时加速度，瞬时方向
    // this.util.tclick(dom, (e: any, data: any)=>{ // starthandler

    // }, (e: any, data: any)=>{// movehandler

    // }, (e: any, data: any)=>{// moveendhandler

    // }, (e: any, data: any)=>{// clickhanlder

    // }, (e: any, data: any)=>{// dblclickhandler

    // }, (e: any, data: any)=>{ // endhandler

    // }, "dblclick", null, null);

    // 各回调自己处理e.stopPropagation();
    tclick: function(dom, starthandler, movehandler, moveendhandler, clickhanlder, dblclickhandler, endhandler, type, mulitclickhandler, mulitClickSum){
        let isModile = ('ontouchstart' in window || window.DocumentTouch && window.document instanceof window.DocumentTouch) || false;
        type = type || 'dblclick';
        let _self = dom;
        let boundingClientRect = dom.getBoundingClientRect();
        let endTime = 0;
        let clickSum = 0;//连击次数
        let clearTime = type == "click" ? 50 : 200;
        let clickDelayTime = 200;
        let clickTimeoutHanlder = null;
        let mulitclickTimeoutHanlder = null;
        let isSureHalf = false;
        let isSureDir = false;
        let targetMouseDown = false;

        if(!isModile){//pc click
            function pcClick(e){
                let startPos = { // 取第一个touch的坐标值
                    x: e.pageX,
                    y: e.pageY,
                    time: new Date().getTime()
                };
                if(clickhanlder) clickhanlder(e, startPos);
            }
            _self.removeEventListener('click', pcClick, false);
            _self.addEventListener('click', pcClick, false);
        }else{// 移动端

            function touchStart(e){
                let isMove = false;
                let isDocMove = false;
                targetMouseDown = true;
                let moveOrder = 0;// 2滑动开始生效
                isSureHalf = false;
                isSureDir = false;
                let touch = e.touches[0]; // touches数组对象获得屏幕上所有的touch，取第一个touch
                let startPos = { // 取第一个touch的坐标值
                    x: touch.pageX,
                    y: touch.pageY,
                    offset: {},
                    half: '',
                    time: new Date().getTime()
                };

                let half = null; // 手势开始所在区域：'left'、'right'
                let dir = null; // 手势方向：x轴、y轴
                let dirPlusorMinus= null; // 瞬时方向：左1、右-1,下1、上-1

                if(!isSureHalf){
                    let offsetLeft = boundingClientRect.left;
                    let offsetTop = boundingClientRect.top;
                    let halfX = offsetLeft + boundingClientRect.width /2;
                    half = startPos.x <= halfX ? "left" : "right";
                    isSureHalf = true;
                    startPos.half = half;
                    startPos.offset = {
                        "top": startPos.y - offsetTop, 
                        "left": startPos.x - offsetLeft, 
                        "right": (offsetLeft + boundingClientRect.width) - startPos.x, 
                        "bottom": (offsetTop + boundingClientRect.height) - startPos.y
                    };
                }
                
                let endPos = startPos;
                // 速度
                let sX = 0, 
                    sY = 0; 
                // 加速度
                let accX = 0, 
                    accY = 0; 
                if(starthandler){
                    starthandler(e, startPos);
                }

                let oldX = startPos.x;
                let _x = startPos.x;
                let oldY = startPos.y;
                let _y = startPos.y;
                let _time = startPos.time;

                // 计算瞬时速度、加速度
                let calculateSpeed = ()=>{
                    let _dT = (_time - endPos.time) / 1000;// 1s = 1000ms
                    if(dir == 'x'){
                        let _dX = _x - endPos.x;
                        dirPlusorMinus = _dX >= 0 ? 1 : -1;
                        let _sX = Math.round(Math.abs(_dX)/_dT * 100)/100;
                        accX = (_sX - sX) / _dT;
                        sX = _sX;
                    }
                    if(dir == 'y'){
                        let _dY = _y - endPos.y;
                        dirPlusorMinus = _dY >= 0 ? 1 : -1;
                        let _sY = Math.round(Math.abs(_dY)/_dT * 100)/100;
                        accY = (_sY - sY) / _dT;
                        sY = _sY;
                    }
                };
                
                function docTouchMove(e){
                    // e.stopPropagation();
                    // e.preventDefault();
                    if(!targetMouseDown) return;
                    let touch1 = e.touches[0];

                    let x = touch1.pageX;
                    let y = touch1.pageY;
                    let moveLen = Math.sqrt(Math.pow(Math.abs(x - oldX), 2) + Math.pow(Math.abs(y - oldX), 2));
                    if(moveLen > 5){
                        isDocMove = true;
                    }
                }

                function touchMove(e1){
                    // e1.stopPropagation();
                    // e1.preventDefault();
                    if(!targetMouseDown) return;
                    let touch1 = e1.touches[0];

                    _x = touch1.pageX;
                    _y = touch1.pageY;
                    _time = new Date().getTime();

                    let moveLen = Math.sqrt(Math.pow(Math.abs(_x - startPos.x), 2) + Math.pow(Math.abs(_y - startPos.y), 2));
                    if(moveLen > 5){
                        isMove = true;
                        
                        if(!isSureDir){
                            if(Math.abs(_x - startPos.x) >= Math.abs(_y - startPos.y)){
                                dir = "x";
                                dirPlusorMinus = _x - startPos.x >= 0 ? 1 : -1;
                            }else{
                                dir = "y";
                                dirPlusorMinus = _y - startPos.y >= 0 ? 1 : -1;
                            }
                            isSureDir = true;
                        }
                        
                        if(moveOrder <=2){
                            moveOrder++;
                            startPos.x = _x;
                            startPos.y = _y;
                        }else{
                            calculateSpeed();
                        // console.log(`speed=====, sX=${sX} px/s, sY=${sY} px/s, accX=${accX} px/s2, accY=${accY} px/s2, dirPlusorMinus=${dirPlusorMinus}`);
                        }
                        endPos = {
                            x: _x,
                            sX: sX,
                            accX: accX,
                            y: _y,
                            sY: sY,
                            accY: accY,
                            time: _time
                        };
                        if(isSureHalf){
                            endPos.half = half;
                        }
                        
                        if(isSureDir){
                            endPos.dir = dir;
                            endPos.dirPlusorMinus = dirPlusorMinus;
                        }
                        if(movehandler){
                            movehandler(e1, endPos, startPos);
                        }
                    }else{
                        startPos.time = _time;
                    }
                }
                function touchEnd(e2){
                    isSureHalf = false;
                    isSureDir = false;
                    if(!targetMouseDown) return;
                    targetMouseDown = false;
                    if(isMove){
                        if(clickTimeoutHanlder) clearTimeout(clickTimeoutHanlder);
                        endTime = 0;
                        clickSum = 0;
                        isDocMove = false;
                        isMove = false;
                        let isStop = false;
                        _time = new Date().getTime();
                        if(_time - endPos.time >= 200 || (dir == 'x' && sX == 0) || (dir == 'y' && sY == 0)){
                            isStop = true;
                            sX = 0;
                            sY = 0;
                            accX = 0;
                            accY = 0;
                        }
                        
                        // 缓冲-减速
                        if(!isStop){
                            // 匀减速
                            let cutTime = 1500;// 减速时间ms
                            
                            let _ss = 0;
                            let _acc = 0;
                            if(dir == 'x'){
                                _ss = sX;
                                _acc = accX;
                            }
                            if(dir == 'y'){
                                _ss = sY;
                                _acc = accY;
                            }
                            // 转换为妙
                            let sCutTime = cutTime/1000; 
                            // 缓冲移动距离
                            endPos.s = _ss * sCutTime - (_ss/sCutTime * sCutTime * sCutTime) / 2;
                            // 缓冲到停止时间
                            endPos.t = sCutTime;

                            let runSpeedF = ()=>{
                                // 模拟缓动～
                                // console.log('cur speed=====', _ss, '---dirPlusorMinus====', dirPlusorMinus);
                            };

                            let speedCut = _ss / cutTime;
                            let tempSS = _ss;
                            let start;
                            // 毫秒级衰减
                            function step(timestamp) {
                                if (start === undefined) start = timestamp;
                                let elapsed = timestamp - start;
                                _ss = tempSS - speedCut * elapsed  <=0 ? 0 : tempSS - speedCut * elapsed;
                                runSpeedF();
                                // 在cutTime后停止动画
                                if (elapsed <= cutTime) { 
                                    window.requestAnimationFrame(step);
                                }
                            }
                            window.requestAnimationFrame(step);
                        }

                        if(moveendhandler) moveendhandler(e2, endPos);
                    }else{
                        let _endTime = new Date().getTime();
                        let isClick = _endTime - startPos.time <= clickDelayTime ? true : false;
                        let isDblclick = endTime ? _endTime - endTime <= clearTime : false;
                        endTime = _endTime;
                        clickSum++; // 记录连击次数
                        console.log(clickSum, isDocMove, isClick);
                        if(!isDocMove && isClick){
                            if(isDblclick){
                                if(clickTimeoutHanlder) clearTimeout(clickTimeoutHanlder);
                                if(mulitclickTimeoutHanlder) clearTimeout(mulitclickTimeoutHanlder);
                                if(mulitClickSum && mulitClickSum > 2){
                                    if(clickSum >= mulitClickSum){
                                        endTime = 0;
                                        clickSum = 0;
                                        if(mulitclickhandler) mulitclickhandler(e2, startPos);
                                    }else if(clickSum >= 2){
                                        mulitclickTimeoutHanlder = setTimeout(()=>{
                                            endTime = 0;
                                            clickSum = 0;
                                            if(dblclickhandler) dblclickhandler(e2, startPos);
                                        }, clearTime);
                                    }
                                }else{
                                    endTime = 0;
                                    clickSum = 0;
                                    if(dblclickhandler) dblclickhandler(e2, startPos);
                                }
                            }else{
                                clickTimeoutHanlder = setTimeout(()=>{
                                    endTime = 0;
                                    clickSum = 0;
                                    if(clickhanlder) clickhanlder(e2, startPos);
                                }, clearTime);
                            }
                        }else if(endhandler && typeof endhandler == "function"){
                            endTime = 0;
                            clickSum = 0;
                            isDocMove = false;
                            endhandler(e2, startPos);
                        }
                    }
                    document.removeEventListener("touchmove", docTouchMove, false);
                    _self.removeEventListener("touchmove", touchMove, false);
                    _self.removeEventListener("touchend", touchEnd, false);
                    _self.removeEventListener("touchcancel", touchCancel, false);
                }
                function touchCancel(e3){
                    isSureHalf = false;
                    isSureDir = false;
                    targetMouseDown = false;
                    endTime = 0;
                    clickSum = 0;
                    isDocMove = false;
                    isMove = false;
                    if(endhandler && typeof endhandler == "function"){
                        endhandler(e3,startPos);
                    }
                    document.removeEventListener("touchmove", docTouchMove, false);
                    _self.removeEventListener("touchmove", touchMove, false);
                    _self.removeEventListener("touchend", touchEnd, false);
                    _self.removeEventListener("touchcancel", touchCancel, false);
                    _self.removeEventListener("contextmenu", touchContextmenu);
                }
                function touchContextmenu(e4){
                    e4 = e4.originalEvent;
                    console.log('contextmenu');
                    isSureHalf = false;
                    isSureDir = false;
                    targetMouseDown = false;
                    endTime = 0;
                    clickSum = 0;
                    isDocMove = false;
                    isMove = false;
                    if(endhandler && typeof endhandler == "function"){
                        endhandler(e4,startPos);
                    }
                    document.removeEventListener("touchmove", docTouchMove, false);
                    _self.removeEventListener("touchmove", touchMove, false);
                    _self.removeEventListener("touchend", touchEnd, false);
                    _self.removeEventListener("touchcancel", touchCancel, false);
                    _self.removeEventListener("contextmenu", touchContextmenu);
                }
                document.removeEventListener("touchmove", docTouchMove, false);
                _self.removeEventListener("touchmove", touchMove, false);
                _self.removeEventListener("touchend", touchEnd, false);
                _self.removeEventListener("touchcancel", touchCancel, false);
                _self.removeEventListener("contextmenu", touchContextmenu);
                document.addEventListener("touchmove", docTouchMove, false);
                _self.addEventListener("touchmove", touchMove, false);
                _self.addEventListener("touchend", touchEnd, false);
                _self.addEventListener("touchcancel", touchCancel, false);
                _self.addEventListener("contextmenu", touchContextmenu);
            }
            _self.removeEventListener("touchstart", touchStart, false);
            _self.addEventListener("touchstart", touchStart, false);//touchstart---end
        }
        return _self;
    },
    uuid: function(){
        return 'xxxxxyxxxxxyxx4xxxyxxxxxyxxxxxyxxxxx'.replace(/[xy]/g, function(c) {
            var r = Math.random()*16|0, v = c == 'x' ? r : (r&0x3|0x8);
            return v.toString(16);
        });
    },
    getData: function(method, url, objJson, headers = {}){
        return new Promise((resolve, reject) =>{
            headers = Object.assign({}, headers || {});
            const _headers = {};
            for (let k in headers) {
                _headers[k] = typeof headers[k] == 'function' ? headers[k]() : headers[k];
            }
            $.ajax({
                type: method,
                url: url,
                headers: _headers,
                contentType: "application/json",
                data: JSON.stringify(objJson),
                success: function(data){
                    resolve(data);
                },
                error: function(jqXHR, textStatus, errorThrown){
                    reject();
                }
            });
        });
    },
    getDataxhr: function(method, url, data){
        return new Promise((resolve, reject) =>{
            var xhr = new XMLHttpRequest();
            xhr.onreadystatechange = (e)=>{
                if (xhr.readyState == 4){
                    alert('xhr.status=='+ xhr.status + ", ==" + JSON.parse(xhr.responseText));
                    if ((xhr.status >= 200 && xhr.status < 300) || xhr.status == 304){
                        resolve(JSON.parse(xhr.responseText));
                    } else {
                        reject(xhr);
                    }
                }
            };
            xhr.open(method, url, true);
            xhr.onloadstart = (e)=>{};
            xhr.onabort = (e)=>{
                console.log('abort');
            };
            try {
                xhr.send(JSON.stringify(data));
                xhr.timeout = 2000;
                xhr.withCredentials = true;
                
            } catch (err){
                xhr.abort();
                reject(err);
            }
            xhr.ontimeout = (err)=>{
                xhr.abort();
                reject({'msg': 'timeout 2s'});
            };
            xhr.onerror = (err)=>{
                reject(err);
            };
            xhr.onload = (e)=>{
                // if (xhr.readyState == 4){
                //     alert('xhr.status=='+ xhr.status);
                //     if ((xhr.status >= 200 && xhr.status < 300) || xhr.status == 304){
                //         resolve(JSON.parse(xhr.responseText));
                //     } else {
                //         reject(xhr);
                //     }
                // }
            };
            xhr.onloadend = (e)=>{};
        });
    }
}
export default util;